package com.open.system.dispatch.impl;

import cn.hutool.core.util.ObjectUtil;
import com.open.common.utils.CollectionUtils;
import com.open.common.utils.ExcelUtils;
import com.open.system.dispatch.IUserDispatch;
import com.open.common.model.Page;
import com.open.base.model.User;
import com.open.system.model.dto.ImportResultDto;
import com.open.system.model.dto.PassWordDto;
import com.open.system.model.dto.UserExcelDto;
import com.open.system.service.IUserService;
import com.open.common.utils.EncryptionUtil;
import com.open.common.utils.ThrowUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

import static com.open.common.constants.Constants.DEFAULT_PASSWORD;

/**
 * 用户信息
 *
 * @author 大树03
 * @date 2025-02-01 22:47
 */
@Component(value = "userDispatch")
@Slf4j
public class UserDispatchImpl implements IUserDispatch {

    private IUserService userService;

    @Autowired
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

	@Override
    public Boolean save(User model) {
        //密码为空，使用默认密码
        String password = model.getPassword();
        if (ObjectUtil.isEmpty(password)) {
            password = DEFAULT_PASSWORD;
        }
        model.setPassword(EncryptionUtil.encode(password));
        //检查用户名唯一
        ThrowUtils.throwIf(!userService.findByModel(new User(model.getUsername())).isEmpty(), "用户名已存在");
        return userService.save(model);
    }

    @Override
    public Boolean update(User model) {
        //ThrowUtils.throwIf(model.getId() == 1 && model.getStatus() != null && model.getStatus() == 1, "不允许停用超级管理员");
        // 检查用户名唯一，排除当前用户ID
        List<User> existingUsers = userService.findByModel(new User(model.getUsername()));
        boolean isDuplicate = existingUsers.stream()
                .anyMatch(existingUser -> !existingUser.getId().equals(model.getId()));
        ThrowUtils.throwIf(isDuplicate, "用户名已存在");
        return userService.update(model);
    }

    @Override
    public Boolean resetPwd(PassWordDto pwd) {
        User user = userService.findByPk(pwd.getUserId());
        if (ObjectUtil.isNotEmpty(pwd.getVerify()) && pwd.getVerify()) {
            ThrowUtils.throwIf(!user.getPassword().equals(EncryptionUtil.encode(pwd.getOldPassword())), "旧密码错误");
        }
        ThrowUtils.throwIf(user.getPassword().equals(EncryptionUtil.encode(pwd.getPassword())), "新密码不能和旧密码相同");
        User model = new User();
        model.setId(pwd.getUserId());
        model.setPassword(EncryptionUtil.encode(pwd.getPassword()));
        return userService.update(model);
    }

    @Override
    public Page<User> findPage(Page<User> page, User item) {
        return userService.findPage(page, item);
    }

    @Override
    public User findByPk(Long pk) {
        return userService.findByPk(pk);
    }

    @Override
    public List<User> findByModel(User model) {
        return userService.findByModel(model);
    }

    @Override
    public Boolean remove(List<Long> ids) {
        ThrowUtils.throwIf(ids.stream().anyMatch(id -> id == 1), "不允许删除超级管理员");
        return userService.remove(ids);
    }

    @Override
    public ImportResultDto importData(MultipartFile file) {
        ImportResultDto result = new ImportResultDto();

        // 读取Excel文件
        List<UserExcelDto> userExcels = ExcelUtils.readExcelSync(file, UserExcelDto.class);
        if (CollectionUtils.isEmpty(userExcels)) {
            ThrowUtils.throwIf(true, "导入失败，文件内容为空");
        }

        result.setTotalCount(userExcels.size());
        List<UserExcelDto> validUsers = new ArrayList<>();
        //用户名
        List<String> usernames = new ArrayList<>();
        Map<String, Long> usernameCountMap = new HashMap<>();

        for (UserExcelDto dto : userExcels) {
            String username = dto.getUsername();

            // 校验必填字段
            if (ObjectUtil.isEmpty(username)) {
                result.addError("未知", "账号不能为空");
                continue;
            }

            // 统计username出现次数
            usernameCountMap.put(username, usernameCountMap.getOrDefault(username, 0L) + 1);
            // 保存username数据
            usernames.add(username);
            validUsers.add(dto);
        }

        // 识别导入数据中重复的username
        Set<String> duplicateUsernames = usernameCountMap.entrySet().stream()
                .filter(entry -> entry.getValue() > 1)
                .map(Map.Entry::getKey)
                .collect(Collectors.toSet());

        List<String> existingUsernames = userService.findExistingUsernames(usernames);
        Set<String> existingUsernameSet = new HashSet<>(existingUsernames);

        Set<String> processedUsernames = new HashSet<>(); // 记录已处理的 username
        List<User> usersToInsert = validUsers.stream()
                .peek(dto -> {
                    String username = dto.getUsername();
                    if (processedUsernames.contains(username)) {
                        return;
                    }
                    processedUsernames.add(username); // 标记为已处理

                    // 记录重复的 username 错误
                    if (duplicateUsernames.contains(username)) {
                        result.addError(username, "导入数据中账号重复");
                    }
                    // 记录数据库中已存在的 username 错误
                    if (existingUsernameSet.contains(username)) {
                        result.addError(username, "数据库中账号已存在");
                    }
                })
                // 过滤输入数据中重复的 username
                .filter(dto -> !duplicateUsernames.contains(dto.getUsername()))
                // 过滤掉数据库中已存在的 username
                .filter(dto -> !existingUsernameSet.contains(dto.getUsername()))
                .map(dto -> {
                    User user = new User();
                    BeanUtils.copyProperties(dto, user);
                    // 设置默认密码
                    user.setPassword(EncryptionUtil.encode(DEFAULT_PASSWORD));
                    // 设置默认状态
                    if (user.getStatus() == null) {
                        user.setStatus(0);
                    }
                    return user;
                })
                .collect(Collectors.toList());


        if (CollectionUtils.isNotEmpty(usersToInsert)) {
            userService.batchSave(usersToInsert);
        }

        result.setSuccessCount(usersToInsert.size());
        log.info("用户数据导入完成，成功：{}条，总数：{}条，错误：{}条", usersToInsert.size(), result.getTotalCount(), result.getErrorList().size());

        return result;
    }
}